import 'dart:io';
import 'dart:isolate';

import 'package:excel_utils/pages/cpc_report/bean/china_post_file_bean.dart';
import 'package:excel_utils/pages/cpc_report/bean/china_post_luggage_bean.dart';
import 'package:excel_utils/pages/cpc_report/bean/fee_item_bean.dart';
import 'package:excel_utils/pages/cpc_report/bean/waybill_managent_bean.dart';
import 'package:excel_utils/pages/cpc_report/cpc_file/bean/cpc_file_result_bean.dart';
import 'package:excel_utils/pages/cpc_report/cpc_file/isloate/cpc_file_isloate.dart';
import 'package:excel_utils/pages/cpc_report/cpc_luggage/bloc/cpc_report_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'cpc_file_event.dart';
import 'cpc_file_state.dart';

class CpcFileBloc extends Bloc<CpcFileEvent, CpcFileAnalysisMergeState> {
  CpcFileBloc()
      : super(const CpcFileAnalysisMergeState(
          waybillManagementLoadingState: false,
          waybillManagementProgress: 0,
          chinaPostFileLoadingState: false,
          chinaPostFileProgress: 0,
          feeItemLoadingState: false,
          feeItemProgress: 0,
          waybillManagementList: [],
          chinaPostFileList: [],
          feeItemList: [],
          writeMsg: "",
          cpcFileResult: [],
          mergeLoadingState: false,
          mergeProgress: 0.00,
        writeProgress: 0.00,
          writeLoadingState: false,
        )) {
    on<CpcFileWaybillManagementEvent>((event, emit) async {
      File? waybillManagementFile = event.file;
      String? waybillManagementName = event.sheetName;
      ReceivePort receivePort = ReceivePort();
      final args = {"file": waybillManagementFile, "sheetName": waybillManagementName, "sendPort": receivePort.sendPort};
      Isolate.spawn(cpcFileWaybillManagementExtraction, args);
      await for (var data in receivePort) {
        if (data["code"] == 0) {
          List<WaybillManagementBean> rowData = data["data"];
          emit(state.copyWith(waybillManagementList: rowData, waybillManagementLoadingState: false, waybillManagementProgress: 1));
          // 结束
          receivePort.close();
        } else if (data["code"] == 1) {
          double progress = data["progress"];
          emit(state.copyWith(waybillManagementProgress: progress));
        }
      }
    });

    // 中油文件
    on<CpcFileChinaPostFileEvent>((event, emit) async {
      File? file = event.file;
      String? sheetName = event.sheetName;
      ReceivePort receivePort = ReceivePort();
      final args = {"file": file, "sheetName": sheetName, "sendPort": receivePort.sendPort};
      Isolate.spawn(cpcFileChinaPostFileExtraction, args);
      await for (var data in receivePort) {
        if (data["code"] == 0) {
          List<ChinaPostFileBean> rowData = data["data"];
          emit(state.copyWith(chinaPostFileList: rowData, chinaPostFileLoadingState: false, chinaPostFileProgress: 1));
          // emit(CpcChinaPostFileState(chinaPostFileList: rowData, message: "中邮数据提取成功"));
          receivePort.close();
        } else if (data["code"] == 1) {
          double progress = data["progress"];
          emit(state.copyWith(chinaPostFileProgress: progress));
          // emit(CpcChinaPostFileLoadingState(progress: progress));
        } else {}
      }
    });

    on<CpcFileFeeitemlistEvent>((event, emit) async {
      File? file = event.file;
      String? sheetName = event.sheetName;
      ReceivePort receivePort = ReceivePort();
      final args = {"file": file, "sheetName": sheetName, "sendPort": receivePort.sendPort};
      Isolate.spawn(cpcFileFeeitemlistExtraction, args);
      await for (var data in receivePort) {
        if (data["code"] == 0) {
          List<FeeItemBean> rowData = data["data"];
          emit(state.copyWith(feeItemList: rowData, feeItemLoadingState: false, feeItemProgress: 1));
          receivePort.close();
          // emit(CpcFeeItemState(feeItemList: rowData, message: "中邮数据提取成功"));
        } else if (data["code"] == 1) {
          double progress = data["progress"];
          emit(state.copyWith(feeItemProgress: progress));
          // emit(CpcFeeItemLoadingState(progress: progress));
        } else {}
      }
    });

    on<CpcFileDataMergeEvent>((event, emit) {
      List<WaybillManagementBean> waybillManagementList = event.waybillManagementList; //基准
      List<ChinaPostFileBean> chinaPostFileList = event.chinaPostFileList;
      List<FeeItemBean> feeItemList = event.feeItemList;

      List<CpcFileResultBean> cpcFileResult = [];
      for (int i = 0; i < waybillManagementList.length; i++) {
        WaybillManagementBean waybillManagement = waybillManagementList[i];
        String uniqueNo = waybillManagement.waybillNumber.toString();
        CpcFileResultBean cpcResultBean = CpcFileResultBean();

        /**
         *  运单管理                   FI       中有文件
         *  G 》F                     D  标识     A  >E
         *  E >B                     J>J         B  >N
         *  D>C                      K>U         I  标识
         *  M>D                                 K>L
         *  H>I                                 R>G
         *  CF>T  标识
            String? waybillNumber;
            String? accountName;
            String? accountNo;
            String? orderAddress;
            String? orderKg;
            String? entryDate;
         */

        cpcResultBean.a = "${i + 1}"; // a 空白
        cpcResultBean.o = "";
        cpcResultBean.l = "";
        cpcResultBean.m = "";
        cpcResultBean.p = "";
        cpcResultBean.q = "";
        cpcResultBean.r = "";
        cpcResultBean.s = "";
        cpcResultBean.u = "";
        cpcResultBean.h = "";

        cpcResultBean.d = (waybillManagement.entryDate != "") ? waybillManagement.entryDate?.substring(0, 10) : "";
        cpcResultBean.b = waybillManagement.accountName;
        cpcResultBean.c = waybillManagement.accountNo;
        cpcResultBean.f = waybillManagement.orderAddress;
        cpcResultBean.i = waybillManagement.orderKg;

        cpcResultBean.t = waybillManagement.waybillNumber;

        FeeItemBean feeItemBean = feeItemList.singleWhere((element) => element.trackingNumber == uniqueNo, orElse: () => FeeItemBean(trackingNumber: "", kg: "", price: ""));
        cpcResultBean.j = (feeItemBean.kg == null || feeItemBean.kg == "") ? "" : double.parse(feeItemBean.kg.toString()).toStringAsFixed(2);
        cpcResultBean.k = (feeItemBean.price == null || feeItemBean.price == "") ? "" : double.parse(feeItemBean.price.toString()).toStringAsFixed(2);

        ChinaPostFileBean chinaPostFileBean = chinaPostFileList.singleWhere((element) => element.trackingNo == uniqueNo, orElse: () => ChinaPostFileBean(trackingNo: "", localCurrentAction: ""));
        // 中有文件  A>E  B>N  I标识  K  R
        cpcResultBean.e = chinaPostFileBean.billedDate;
        cpcResultBean.n = chinaPostFileBean.amount;
        cpcResultBean.l = chinaPostFileBean.cXCAmount;
        cpcResultBean.g = chinaPostFileBean.localCurrentAction;


        cpcFileResult.add(cpcResultBean);
      }
      emit(state.copyWith(cpcFileResult: cpcFileResult));
    });
    on<CpcFileWriteFileEvent>((event, emit) async {
      emit(state.copyWith(writeLoadingState:true));

      // emit(CpcWriteFileLoadingState(progress: 0));
      List<CpcFileResultBean> cpcResultList = event.cpcResultList;
      File writeFile = event.writeFile;
      String writeName = event.writeName;
      ReceivePort receivePort = ReceivePort();
      final args = {
        "cpcResultList": cpcResultList,
        "writeFile": writeFile,
        "sheetName": writeName,
        "sendPort": receivePort.sendPort,
      };
      Isolate.spawn(cpcFileWriteDataToExcel, args);
      await for (var data in receivePort) {
        if (data["code"] == 0) {

          emit(state.copyWith(writeMsg: "数据写入成功",writeLoadingState:false,writeProgress: 1));
          // emit(CpcWriteFileSuccessState());
        } else if (data["code"] == 2) {

          emit(state.copyWith(progress:data["progress"] ?? 0.0,writeMsg: "正在写入数据"));
          // emit(CpcWriteFileLoadingState(progress: data["progress"] ?? 0.0));
        } else {
          // emit(CpcWriteFileFailureState(failureMessage: "数据写入失败"));
          emit(state.copyWith(progress: 0.0,writeMsg: "数据写入失败"));
        }
      }

    });
  }
}
